package server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

/**
 * @author Elvis
 * @version 1.0, 2024-02-28 14:10:22
 */
public class HttpProcessor implements Runnable {

    private final HttpConnector connector;
    private volatile boolean busying = false;
    private volatile Socket socket;


    public HttpProcessor(HttpConnector connector) {
        this.connector = connector;
    }

    @Override
    public void run() {
        while (true) {
            try (Socket await = this.await()) {
                if (await == null) {
                    continue;
                }
                System.out.println("accept socket" + Thread.currentThread().getName());
                this.process(await);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                connector.recycleProcessor(this);
            }
        }
    }

    public synchronized void assign(Socket accept) {
        while (busying) {
            try {
                super.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        this.socket = accept;
        busying = true;
        super.notifyAll();
    }

    /**
     * await
     */
    public synchronized Socket await() {
        while (!busying) {
            try {
                super.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        // 通知Connector我们已经收到这个Socket了
        Socket socket = this.socket;
        busying = false;
        notifyAll();
        return (socket);
    }

    public void process(Socket accept) throws IOException {
        try {
            System.out.println(Thread.currentThread().getName() + "----" + "process thread");
            TimeUnit.SECONDS.sleep(0);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        InputStream inputStream = accept.getInputStream();
        OutputStream outputStream = accept.getOutputStream();
        HttpRequest httpRequest = new HttpRequest(inputStream);
        httpRequest.parse(accept);

        // handle session
        if (httpRequest.getSessionId() == null || httpRequest.getSessionId().equals("")) {
            httpRequest.getSession(true);
        }
        // Request request = new Request(inputStream);
        // request.parse();
        // Response response = new Response();
        // response.setRequest(request);
        // response.setOutputStream(outputStream);
        HttpResponse response = new HttpResponse(outputStream);
        response.setRequest(httpRequest);

        if (httpRequest.getRequestURI().startsWith("/servlet/")) {
            ServletProcessor processor = new ServletProcessor();
            processor.process(httpRequest, response);
        } else {
            StaticResourceProcessor processor = new StaticResourceProcessor();
            processor.process(httpRequest, response);
        }
        accept.close();
    }


    public void start(int threadNum) {
        new Thread(this, "HttpProcessor " + threadNum).start();
    }

}
